package mobilecontrollers

import (
	"alarmservice/com"
	"alarmservice/www/apistore"
	"strings"
	"time"

	"github.com/astaxie/beego"
	simplejson "github.com/bitly/go-simplejson"
)

type baseControllerInterface interface {
	beego.ControllerInterface
	NextPrepare()
}

type baseController struct {
	beego.Controller
	ParamsJson *simplejson.Json
	HaveParams bool
	NeedParams bool
	Token      *apistore.Token
}

func (c *baseController) Prepare() {
	c.HaveParams = false
	c.paddingGetPost()
	c.parseRequest()

	if app, ok := c.AppController.(baseControllerInterface); ok {
		app.NextPrepare()
	}

	if c.NeedParams && !c.HaveParams {
		c.returnJson(com.ApiUnknowFailed(com.ApiErrMsgNoJson))
		return
	}
}

func (c *baseController) returnJson(j *com.JsonApiRep, encode ...bool) {
	c.Data["json"] = j
	c.ServeJSON(encode...)
	return
}

func (c *baseController) parseRequest() {

	ctx := c.Ctx

	if ctx.Input.Method() != "POST" {
		ctx.Output.SetStatus(500)
		c.returnJson(com.ApiReturn(100, "need post method", nil))
		return
	}

	//解析json数据

	if len(ctx.Input.RequestBody) > 0 {
		var err error
		c.ParamsJson, err = simplejson.NewJson(ctx.Input.RequestBody)
		if err != nil {
			c.ParamsJson = simplejson.New()
		} else {
			c.HaveParams = true
		}
	}

	uri := strings.ToLower(ctx.Request.RequestURI)
	//login不需要处理
	if strings.Index(uri, "/mapi/login") == 0 {
		return
	}

	tokenValue := ctx.Request.Header.Get("Token")
	reqMd5Sign := ctx.Request.Header.Get("Md5")
	reqBody := string(ctx.Input.RequestBody)

	token, err := apistore.GetToken(tokenValue)

	if err != nil {
		ctx.Output.SetStatus(401)
		c.returnJson(com.ApiReturn(100, com.ApiErrMsgTokenInvalid, nil))
		return
	}

	if token.Expires < time.Now().Unix() {
		ctx.Output.SetStatus(401)
		c.returnJson(com.ApiReturn(101, com.ApiErrMsgTokenExpired, nil))
	}

	strForMd5Sign := reqBody + token.Value

	md5Sign := apistore.Sign(strForMd5Sign, token.Key)

	if beego.AppConfig.String("runmode") == "dev" {
		beego.Debug("str_for_md5:" + strForMd5Sign + "|||md5sign:" + md5Sign)
	}

	if md5Sign != reqMd5Sign {
		ctx.Output.SetStatus(401)
		c.returnJson(com.ApiReturn(102, com.ApiErrMsgSign, nil))
		return
	}

	c.Token = token
}

func (c *baseController) paddingGetPost() {
	c.Ctx.Request.ParseForm()

	c.Data["FormVar"] = c.Ctx.Request.Form
	c.Data["PostFormVar"] = c.Ctx.Request.PostForm

	getVars := make(map[string]string)
	postVars := make(map[string]string)
	for k, v := range c.Ctx.Request.Form {
		vLen := len(v)
		if vLen > 0 {
			getVars[k] = v[len(v)-1]
		} else {
			getVars[k] = ""
		}
	}

	for k, v := range c.Ctx.Request.PostForm {
		vLen := len(v)
		if vLen > 0 {
			postVars[k] = v[len(v)-1]
		} else {
			postVars[k] = ""
		}
	}

	c.Data["GET"] = getVars
	c.Data["POST"] = postVars
}

type MainController struct {
	beego.Controller
}

func (c *MainController) Get() {
	c.Data["Website"] = "beego.me"
	c.Data["Email"] = "astaxie@gmail.com"
	c.TplName = "index.tpl"
}
